import { Inject, Injectable } from '@angular/core';
import { CookieService } from 'ngx-cookie-service';
import { HttpService } from './http.service';
import { LoginInfoService } from './login-info.service';
import { HttpHeaders } from '@angular/common/http';
import { error } from '@ant-design/icons-angular';
import { Observable } from 'rxjs';
import { ApiResult } from '../models/api.result';
import { TokenResponse } from '../models/token-response';
import { REDIRECT_ADDR, RES_URL, SERVER_ADDR } from '../app.component';

@Injectable({
  providedIn: 'root'
})
export class AppService {

  public clientId = 'res-test1';
  public redirectUri = '';
  public serverUrl = '';

  constructor(private _http: HttpService, private cookieService: CookieService,
  private _loginInfoService: LoginInfoService,
  @Inject(RES_URL) private baseUrl: string,
  @Inject(REDIRECT_ADDR) private redirectUrlParam: string,
  @Inject(SERVER_ADDR) private serverAddrParam: string,) {
    this.redirectUri = redirectUrlParam;
    this.serverUrl = serverAddrParam;
   }

  retrieveToken(code: string){
    const params = new URLSearchParams();   
    params.append('grant_type','authorization_code');
    params.append('client_id', this.clientId);
    params.append('redirect_uri', this.redirectUri);
    params.append('code',code);
    console.log(`ready to retrive token with ${this.redirectUri}, ${code}`);
 
    let headers = new HttpHeaders({'Content-type': 'application/x-www-form-urlencoded; charset=utf-8',
    'Authorization': "Basic " + btoa("res-test1:123456")});
 //   const headers = new HttpHeaders({'Content-type': 'application/x-www-form-urlencoded; charset=utf-8',
 //  'Authorization': 'Basic bWVzc2FnaW5nLWNsaWVudDoxMjM0NTY='});
    const resp = this._http.postWithHeaders<TokenResponse>(`${this.serverUrl}/oauth2/token`, params.toString(), headers);
    console.log(`Post returned ${resp} with type ` + typeof(resp));
    resp.subscribe({
     next: resp => {
       console.log(`oauth token get response ${resp.access_token}`);
       this.saveRefreshToken(resp);
       this.saveToken(resp);

       this._loginInfoService.isLoggedIn.next(true);
     },
     error: () => {
       console.log(`'subscribe error ${error}`);
     }
    });
    
    //this._http.post('http://localhost:20110/oauth2/token', params.toString(), { headers: headers })
    //.subscribe(
    //  data => this.saveToken(data),
    //  err => alert('Invalid Credentials')
    //); 
  }

  refreshToken() {
    const refreshToken = this.cookieService.get('refresh_token');
    if (refreshToken == null || refreshToken === '') {
      return;
    }

    const params = new URLSearchParams();
    params.append('grant_type', 'refresh_token');
    params.append('refresh_token', refreshToken);

    const headers = new HttpHeaders({
      'Content-type': 'application/x-www-form-urlencoded; charset=utf-8',
      'Authorization': "Basic " + btoa(this.clientId + ":123456")
    });

    const resp = this._http.postWithHeaders<TokenResponse>(`${this.serverUrl}/oauth2/token`, params.toString(), headers);
    console.log(`refresh token returned ${JSON.stringify(resp)}`);
    if (resp == null) {
      return;
    }

    resp.subscribe({
      next: resp => {
        console.log(`refresh token get response ${resp.access_token}`);
        
        const expireDate = new Date().getTime() + (1000 * resp.expires_in);
        this.cookieService.set("access_token", resp.access_token, expireDate);
      },
      error: () => {
        console.log(`'refresh token error ${error}`);
      }
    });
  }
  saveRefreshToken(token: TokenResponse) {
    this.cookieService.set('refresh_token', token.refresh_token);
  }
  saveToken(token: TokenResponse){
    var expireDate = new Date().getTime() + (1000 * token.expires_in);
    this.cookieService.set("access_token", token.access_token, expireDate);
 //   this.cookieService.set("id_token", token.id_token, expireDate);
    console.log('Obtained Access token');
    this._loginInfoService.isLoggedIn.next(true);
    window.location.href = this.redirectUri;
  }
 
 
 
  getResource(resourceUrl: string) : Observable<ApiResult<string>>{
   var token = this.cookieService.get('access_token');
    var headers = new HttpHeaders({'Content-type': 'application/x-www-form-urlencoded','Authorization': 'Bearer ' + token});
    console.log(`get resource with token ${token}`);
    return this._http.getWithHeaders<ApiResult<string>>(resourceUrl, headers);
  }
  
  checkCredentials(){
    return this.cookieService.check('access_token');
  } 
 
  removeToken() {
   this.cookieService.delete('access_token');
   this.cookieService.delete('id_token');
  }
 
 
  logout() {
    this.cookieService.delete('access_token');
    this.cookieService.delete('JSESSIONID');
    console.log(`deleted cookies, redirect to home`);

    const logoutURL = this.serverUrl + "/logout?post_logout_redirect_uri=" + this.redirectUri;
    console.log(`Logout to ${logoutURL}`);
    window.location.href = logoutURL;
    this._loginInfoService.isLoggedIn.next(false);
  } 
}
